package GUI;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;

import Verwaltung.Daten.Interfaces.ILehrkraft;
import Verwaltung.Rechtecontroler.PermissionException;

/**
 * 
 * @author MaximumDataOverdrive
 * 
 */
public class LehrerEditDialog extends JDialog implements ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = -61949617856507140L;
	private JLabel lblName;
	private JTextField jNameTextField;
	private JComboBox<ILehrkraft> comboBox;
	private JSeparator separator;
	private JPanel panel;
	private JButton btnLschen;
	private JButton btnSpeichern;
	private JButton btnNeu;
	private JButton btnAbbrechen;
	private JLabel lblLoginname;
	private JTextField jLoginNameTextField;
	private JLabel lblPasswort;
	private JTextField jPasswortTextField;
	private JCheckBox chckbxIstLehrer;
	private JFormattedTextField jWochenStundenFormattedTextField;
	private JLabel lblWochenstunden;
	private JComboBox<String> jZugriffsLevelComboBox;
	private JLabel lblZugriffslevel;

	/**
	 * Konstruktor des Lehrer-Editier-Dialoges
	 */
	public LehrerEditDialog(final JFrame frame) {
		super(frame);

		initialize();
	}

	/**
	 * Diese Methode initialisert die GUI des Lehrer-Editier-Dialoges
	 */
	private void initialize() {
		final GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 21, 0 };
		gridBagLayout.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
				0.0, 0.0, 0.0, Double.MIN_VALUE };
		getContentPane().setLayout(gridBagLayout);
		final GridBagConstraints gbc_comboBox = new GridBagConstraints();
		gbc_comboBox.gridwidth = 2;
		gbc_comboBox.insets = new Insets(0, 0, 5, 0);
		gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_comboBox.gridx = 0;
		gbc_comboBox.gridy = 0;
		getContentPane().add(getComboBox(), gbc_comboBox);
		final GridBagConstraints gbc_separator = new GridBagConstraints();
		gbc_separator.gridwidth = 2;
		gbc_separator.insets = new Insets(0, 0, 5, 0);
		gbc_separator.gridx = 0;
		gbc_separator.gridy = 1;
		getContentPane().add(getSeparator(), gbc_separator);
		final GridBagConstraints gbc_lblName = new GridBagConstraints();
		gbc_lblName.insets = new Insets(5, 5, 5, 5);
		gbc_lblName.anchor = GridBagConstraints.EAST;
		gbc_lblName.gridx = 0;
		gbc_lblName.gridy = 2;
		getContentPane().add(getLblName(), gbc_lblName);
		final GridBagConstraints gbc_jNameTextField = new GridBagConstraints();
		gbc_jNameTextField.insets = new Insets(0, 0, 5, 0);
		gbc_jNameTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_jNameTextField.gridx = 1;
		gbc_jNameTextField.gridy = 2;
		getContentPane().add(getJNameTextField(), gbc_jNameTextField);
		final GridBagConstraints gbc_lblLoginname = new GridBagConstraints();
		gbc_lblLoginname.anchor = GridBagConstraints.EAST;
		gbc_lblLoginname.insets = new Insets(0, 0, 5, 5);
		gbc_lblLoginname.gridx = 0;
		gbc_lblLoginname.gridy = 3;
		getContentPane().add(getLblLoginname(), gbc_lblLoginname);
		final GridBagConstraints gbc_jLoginNameTextField = new GridBagConstraints();
		gbc_jLoginNameTextField.insets = new Insets(0, 0, 5, 0);
		gbc_jLoginNameTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_jLoginNameTextField.gridx = 1;
		gbc_jLoginNameTextField.gridy = 3;
		getContentPane().add(getJLoginNameTextField(), gbc_jLoginNameTextField);
		final GridBagConstraints gbc_lblPasswort = new GridBagConstraints();
		gbc_lblPasswort.insets = new Insets(0, 0, 5, 5);
		gbc_lblPasswort.anchor = GridBagConstraints.EAST;
		gbc_lblPasswort.gridx = 0;
		gbc_lblPasswort.gridy = 4;
		getContentPane().add(getLblPasswort(), gbc_lblPasswort);
		final GridBagConstraints gbc_jPasswortTextField = new GridBagConstraints();
		gbc_jPasswortTextField.insets = new Insets(0, 0, 5, 0);
		gbc_jPasswortTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_jPasswortTextField.gridx = 1;
		gbc_jPasswortTextField.gridy = 4;
		getContentPane().add(getJPasswortTextField(), gbc_jPasswortTextField);
		final GridBagConstraints gbc_lblWochenstunden = new GridBagConstraints();
		gbc_lblWochenstunden.insets = new Insets(0, 0, 5, 5);
		gbc_lblWochenstunden.anchor = GridBagConstraints.EAST;
		gbc_lblWochenstunden.gridx = 0;
		gbc_lblWochenstunden.gridy = 5;
		getContentPane().add(getLblWochenstunden(), gbc_lblWochenstunden);
		final GridBagConstraints gbc_jWochenStundenFormattedTextField = new GridBagConstraints();
		gbc_jWochenStundenFormattedTextField.insets = new Insets(0, 0, 5, 0);
		gbc_jWochenStundenFormattedTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_jWochenStundenFormattedTextField.gridx = 1;
		gbc_jWochenStundenFormattedTextField.gridy = 5;
		getContentPane().add(getJWochenStundenFormattedTextField(),
				gbc_jWochenStundenFormattedTextField);
		final GridBagConstraints gbc_lblZugriffslevel = new GridBagConstraints();
		gbc_lblZugriffslevel.insets = new Insets(0, 0, 5, 5);
		gbc_lblZugriffslevel.anchor = GridBagConstraints.EAST;
		gbc_lblZugriffslevel.gridx = 0;
		gbc_lblZugriffslevel.gridy = 6;
		getContentPane().add(getLblZugriffslevel(), gbc_lblZugriffslevel);
		final GridBagConstraints gbc_jZugriffsLevelComboBox = new GridBagConstraints();
		gbc_jZugriffsLevelComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_jZugriffsLevelComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_jZugriffsLevelComboBox.gridx = 1;
		gbc_jZugriffsLevelComboBox.gridy = 6;
		getContentPane().add(getJZugriffsLevelComboBox(),
				gbc_jZugriffsLevelComboBox);
		final GridBagConstraints gbc_chckbxIstLehrer = new GridBagConstraints();
		gbc_chckbxIstLehrer.insets = new Insets(0, 0, 5, 0);
		gbc_chckbxIstLehrer.gridx = 1;
		gbc_chckbxIstLehrer.gridy = 7;
		getContentPane().add(getChckbxIstLehrer(), gbc_chckbxIstLehrer);
		final GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.gridwidth = 2;
		gbc_panel.fill = GridBagConstraints.BOTH;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 8;
		getContentPane().add(getPanel(), gbc_panel);
	}

	/**
	 * Diese Methode gibt das Label mit "Name" zurück. Gibt es dieses nicht,
	 * wird es neu initialisert.
	 * 
	 * @return lblName Label indem "Name" steht.
	 */
	private JLabel getLblName() {
		if (lblName == null) {
			lblName = new JLabel("Name");
		}
		return lblName;
	}

	/**
	 * Diese Methode gibt das Text-Feld für den Namen der Lehrkraft zurück. Gibt
	 * es dieses nicht, wird es neu initialisert.
	 * 
	 * @return jNameTextField Text-Feld indem der Name der Lehrkraft steht
	 */
	private JTextField getJNameTextField() {
		if (jNameTextField == null) {
			jNameTextField = new JTextField();
			jNameTextField.setColumns(10);
		}
		return jNameTextField;
	}

	/**
	 * Diese Methode gibt die ComboBox mit den vorhandenen Lehrkräften zurück.
	 * Gibt es diese nicht, wird diese neu initialisert.
	 * 
	 * @return comboBox ComboBox mit den verfügbaren Lehrkräften
	 */
	private JComboBox<ILehrkraft> getComboBox() {
		if (comboBox == null) {
			comboBox = new JComboBox<ILehrkraft>();

			try {
				updateCombobox();
			} catch (final PermissionException e) {
				e.printStackTrace();
			}

			comboBox.setSelectedIndex(0);
		}
		return comboBox;
	}

	/**
	 * Diese Methode ist gibt ein optisches Element zurück und erzeugt dieses
	 * gegebenenfalls neu.
	 * 
	 * @return separator Linie
	 */
	private JSeparator getSeparator() {
		if (separator == null) {
			separator = new JSeparator();
		}
		return separator;
	}

	/**
	 * Diese Methode gibt das Panel zurück, der die Buttons für die
	 * Funktionalität des Dialoges enthält. Existiert dieses nicht, wird dieses
	 * neu erzeugt.
	 * 
	 * @return panel Anzeige mit Bedienelementen des Dialoges.
	 */
	private JPanel getPanel() {
		if (panel == null) {
			panel = new JPanel();
			final GridBagLayout gbl_panel = new GridBagLayout();
			gbl_panel.columnWidths = new int[] { 0, 0, 0, 0, 0 };
			gbl_panel.rowHeights = new int[] { 0, 0 };
			gbl_panel.columnWeights = new double[] { 1.0, 1.0, 1.0, 1.0,
					Double.MIN_VALUE };
			gbl_panel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
			panel.setLayout(gbl_panel);
			final GridBagConstraints gbc_btnLschen = new GridBagConstraints();
			gbc_btnLschen.insets = new Insets(0, 0, 0, 5);
			gbc_btnLschen.gridx = 0;
			gbc_btnLschen.gridy = 0;
			panel.add(getBtnLschen(), gbc_btnLschen);
			final GridBagConstraints gbc_btnSpeichern = new GridBagConstraints();
			gbc_btnSpeichern.insets = new Insets(0, 0, 0, 5);
			gbc_btnSpeichern.gridx = 1;
			gbc_btnSpeichern.gridy = 0;
			panel.add(getBtnSpeichern(), gbc_btnSpeichern);
			final GridBagConstraints gbc_btnNeu = new GridBagConstraints();
			gbc_btnNeu.insets = new Insets(0, 0, 0, 5);
			gbc_btnNeu.gridx = 2;
			gbc_btnNeu.gridy = 0;
			panel.add(getBtnNeu(), gbc_btnNeu);
			final GridBagConstraints gbc_btnAbbrechen = new GridBagConstraints();
			gbc_btnAbbrechen.gridx = 3;
			gbc_btnAbbrechen.gridy = 0;
			panel.add(getBtnAbbrechen(), gbc_btnAbbrechen);
		}
		return panel;
	}

	/**
	 * Diese Methode gibt den Button: btnLschen zurück. Existiert dieser nicht,
	 * wird er neu initialisert.
	 * 
	 * @return btnLschen Button der das Löschen eines Lehrers ermöglicht.
	 */
	private JButton getBtnLschen() {
		if (btnLschen == null) {
			btnLschen = new JButton("Löschen");
			btnLschen.addActionListener(this);
		}
		return btnLschen;
	}

	/**
	 * Diese Methode gibt den Button: btnSpeichern zurück. Existiert dieser
	 * nicht, wird er neu initialisert.
	 * 
	 * @return btnSpeichern Button der das Speichern eines Lehrers ermöglicht
	 */
	private JButton getBtnSpeichern() {
		if (btnSpeichern == null) {
			btnSpeichern = new JButton("Speichern");
			btnSpeichern.addActionListener(this);
		}
		return btnSpeichern;
	}

	/**
	 * Diese Methode gibt den Button: btnNeu zurück. Existiert dieser nicht,
	 * wird er neu initialisert.
	 * 
	 * @return btnNeu Button der das Erstellen eines neuen Lehrers ermöglicht.
	 */
	private JButton getBtnNeu() {
		if (btnNeu == null) {
			btnNeu = new JButton("Neu");
			btnNeu.addActionListener(this);
		}
		return btnNeu;
	}

	/**
	 * Diese Methode gibt den Button: btnAbbrechen zurück. Existiert dieser
	 * nicht, wird er neu initialisert.
	 * 
	 * @return btnAbbrechen Button der die Editierung eines neuen Lehrers
	 *         abbricht.
	 */
	private JButton getBtnAbbrechen() {
		if (btnAbbrechen == null) {
			btnAbbrechen = new JButton("Abbrechen");
			btnAbbrechen.addActionListener(this);
		}
		return btnAbbrechen;
	}

	/**
	 * Diese Methode enthält alle Funktionen, die bei der Betätigung der
	 * jeweiligen Elemente ausgeführt werden. Dabei wird bei den if-Bedigungen
	 * geprüft, welches Element betätigt worden ist und die gewünschte Funktion
	 * wird ausgeführt.
	 */
	@Override
	public void actionPerformed(final ActionEvent av) {
		if (av.getSource() == getBtnAbbrechen()) {

			setVisible(false);
			dispose();
		} else if (av.getSource() == getBtnLschen()) {
			try {
				StundenplanController
						.getInstance()
						.getRechteController()
						.removeLehrkraft(
								getComboBox().getSelectedItem().toString());
				updateCombobox();
			} catch (final PermissionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			StundenplanController.getInstance().update();

		} else if (av.getSource() == getBtnSpeichern()) {

			try {
				int permissionLevel = 0;
				if (getJZugriffsLevelComboBox().getSelectedItem().toString()
						.equals("Admin")) {
					permissionLevel = 1;
				}

				if(getComboBox().getSelectedItem() == null) {
					
					JOptionPane.showMessageDialog(this, "Kein Lehrer ausgewählt");
					return;
				}
				
				try {
				StundenplanController
						.getInstance()
						.getRechteController()
						.editLehrkraft(
								getComboBox().getSelectedItem().toString(),
								getJLoginNameTextField().getText(),
								getJNameTextField().getText(),
								Integer.parseInt(getJWochenStundenFormattedTextField()
										.getValue().toString()),
								getJPasswortTextField().getText(),
								permissionLevel,
								getChckbxIstLehrer().isSelected());
				StundenplanController.getInstance().update();
				updateCombobox();
				} catch (IllegalArgumentException e) {
					JOptionPane.showMessageDialog(this, e.getMessage());
				}
				
			} catch (final PermissionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			StundenplanController.getInstance().update();

		} else if (av.getSource() == getBtnNeu()) {
			try {

				final String lehrkraft = (String) JOptionPane
						.showInputDialog(
								this,
								"Den neuen eindeutigen LoginNamen der Lehrkraft eingeben",
								"Lehrkraft Neu", JOptionPane.PLAIN_MESSAGE,
								null, null, "");

				// If a string was returned, say so.
				if ((lehrkraft != null) && (lehrkraft.length() > 2)) {
					
					if(StundenplanController.getInstance()
									.getRechteController().getLehrkraft(lehrkraft) != null) {
						JOptionPane.showMessageDialog(this, "Loginname schon vergeben");
						return;
					}
					

					final String name = (String) JOptionPane.showInputDialog(
							this, "Den Namen der Lehrkraft eingeben",
							"Lehrkraft Neu", JOptionPane.PLAIN_MESSAGE, null,
							null, "");

					// If a string was returned, say so.
					if ((name != null) && (name.length() > 2)) {

						final String pass = (String) JOptionPane
								.showInputDialog(this,
										"Das Passwort der Lehrkraft eingeben",
										"Lehrkraft Neu",
										JOptionPane.PLAIN_MESSAGE, null, null,
										"");

						// If a string was returned, say so.
						if ((pass != null) && (pass.length() > 2)) {

							StundenplanController.getInstance()
									.getRechteController()
									.addLehrer(lehrkraft, name, 0, pass, 0);
							JOptionPane.showMessageDialog(null,
									"Erfolgreich erstellt");
							updateCombobox();

							return;
						}
					}
				}

			} catch (final PermissionException e) {
				// TODO Handle exception
				JOptionPane.showMessageDialog(null, "Fehler beim Erstellen");
				e.printStackTrace();
			}
			StundenplanController.getInstance().update();

		} else if (av.getSource() == getComboBox()) {

			if (getComboBox().getSelectedItem() != null) {
				ILehrkraft lehrkraft;
				try {
					lehrkraft = StundenplanController
							.getInstance()
							.getRechteController()
							.getLehrkraft(
									getComboBox().getSelectedItem().toString());

					getJNameTextField().setText(lehrkraft.getName());
					getJLoginNameTextField().setText(lehrkraft.getLoginName());
					getJPasswortTextField().setText(
							lehrkraft.getPassword().toString());
					getJWochenStundenFormattedTextField().setValue(
							lehrkraft.getWochenstunden());

					getJZugriffsLevelComboBox().setSelectedIndex(
							lehrkraft.getPermissionLvl());

					getChckbxIstLehrer().setSelected(
							lehrkraft.darfUnterrichten());

				} catch (final PermissionException e) {
					JOptionPane.showMessageDialog(this, "Permission Fehler");
					e.printStackTrace();
				}
			}
		}

	}

	/**
	 * Diese Methode realisert das Updaten der Einträge in der ComboBox. Sie
	 * lädt also alle aktuell existierenden Lehrkräfte hinein.
	 * 
	 * @throws PermissionException
	 *             Da die Exception bei Methoden des Rechtecontrolers geworfen
	 *             wird.
	 */
	private void updateCombobox() throws PermissionException {

		// //getComboBox().removeActionListener(this);

		final Object selected = getComboBox().getSelectedItem();
		getComboBox().removeActionListener(this);

		final DefaultComboBoxModel<ILehrkraft> model = new DefaultComboBoxModel<ILehrkraft>();
		model.removeAllElements();

		for (final ILehrkraft lehr : StundenplanController.getInstance()
				.getRechteController().getAlleLehrkraefte()) {
			model.addElement(lehr);
		}
		getComboBox().setModel(model);
		getComboBox().addActionListener(this);

		if (selected != null) {
			getComboBox().setSelectedItem(selected);
		}

	}

	/**
	 * Diese Methode gibt das Label mit "Loginname" zurück. Gibt es dieses
	 * nicht, wird es neu initialisert.
	 * 
	 * @return lblLoginname Label indem "Loginname" steht.
	 */
	private JLabel getLblLoginname() {
		if (lblLoginname == null) {
			lblLoginname = new JLabel("Loginname");
		}
		return lblLoginname;
	}

	/**
	 * Diese Methode gibt das Text-Feld für den Login-Namen der Lehrkraft
	 * zurück. Gibt es dieses nicht, wird es neu initialisert.
	 * 
	 * @return jLoginNameTextField Text-Feld indem der Login-Name der Lehrkraft
	 *         steht
	 */
	private JTextField getJLoginNameTextField() {
		if (jLoginNameTextField == null) {
			jLoginNameTextField = new JTextField();
			jLoginNameTextField.setColumns(10);
		}
		return jLoginNameTextField;
	}

	/**
	 * Diese Methode gibt das Label mit "Passwort" zurück. Gibt es dieses nicht,
	 * wird es neu initialisert.
	 * 
	 * @return lblPasswort Label indem "Passwort" steht.
	 */
	private JLabel getLblPasswort() {
		if (lblPasswort == null) {
			lblPasswort = new JLabel("Passwort");
		}
		return lblPasswort;
	}

	/**
	 * Diese Methode gibt das Text-Feld für das Passwort der Lehrkraft zurück.
	 * Gibt es dieses nicht, wird es neu initialisert.
	 * 
	 * @return jPasswortTextField Text-Feld indem das Passwort der Lehrkraft
	 *         steht
	 */
	private JTextField getJPasswortTextField() {
		if (jPasswortTextField == null) {
			jPasswortTextField = new JTextField();
			jPasswortTextField.setColumns(10);
		}
		return jPasswortTextField;
	}

	/**
	 * Diese Methode gibt eine Check-Box zurück, in der ausgewählt werden kann,
	 * ob die Lehrkraft unterrichten darf, damit realisieren wir den Betreuer.
	 * Gib es diese Check-Box nicht, wird sie neu erzeugt.
	 * 
	 * @return chckbxIstLehrer7 Auswahlfeld, ob es sich um einen Lehrer oder
	 *         Betreuer handelt.
	 */
	private JCheckBox getChckbxIstLehrer() {
		if (chckbxIstLehrer == null) {
			chckbxIstLehrer = new JCheckBox("Ist Lehrer");
		}
		return chckbxIstLehrer;
	}

	/**
	 * Diese Methode gibt ein Textfeld(nur mit Zahlen - gilt für alle
	 * JFormattedText_Felder unserer GUI) zurück, in das die Wochenstunden eines
	 * Lehrers eingetragen werden. Existiert dieses nicht, so wird es neu
	 * erzeugt.
	 * 
	 * @return jWochenStundenFormattedTextField Textfeld für die Wochenstunden
	 *         die eine Lehrkraft arbeiten kann.
	 */
	private JFormattedTextField getJWochenStundenFormattedTextField() {
		if (jWochenStundenFormattedTextField == null) {
			final NumberFormat integerNumberInstance = NumberFormat
					.getIntegerInstance();
			jWochenStundenFormattedTextField = new JFormattedTextField(
					integerNumberInstance);
		}
		return jWochenStundenFormattedTextField;
	}

	/**
	 * Diese Methode gibt das Label mit "Wochenstunden" zurück. Gibt es dieses
	 * nicht, wird es neu initialisert.
	 * 
	 * @return lblWochenstunden Label indem "Wochenstunden" steht.
	 */
	private JLabel getLblWochenstunden() {
		if (lblWochenstunden == null) {
			lblWochenstunden = new JLabel("Wochenstunden");
		}
		return lblWochenstunden;
	}

	/**
	 * Diese Methode gibt die ComboBox mit den verfügbaren Zugriffs-Leveln
	 * zurück. Gibt es diese nicht, wird diese neu initialisert.
	 * 
	 * @return jZugriffsLevelComboBox ComboBox mit den verfügbaren
	 *         Zugriffs-Leveln
	 */
	private JComboBox<String> getJZugriffsLevelComboBox() {
		if (jZugriffsLevelComboBox == null) {
			jZugriffsLevelComboBox = new JComboBox<String>();

			final DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
			model.addElement("Normal");
			model.addElement("Admin");
			jZugriffsLevelComboBox.setModel(model);
		}
		return jZugriffsLevelComboBox;
	}

	/**
	 * Diese Methode gibt das Label mit "Zugriffslevel" zurück. Gibt es dieses
	 * nicht, wird es neu initialisert.
	 * 
	 * @return lblZugriffslevel Label indem "Zugriffslevel" steht.
	 */
	private JLabel getLblZugriffslevel() {
		if (lblZugriffslevel == null) {
			lblZugriffslevel = new JLabel("Zugriffslevel");
		}
		return lblZugriffslevel;
	}
}
